#include "resource_manage.h"
#include <iostream>
#include "json/json.h"
#include <fstream>
#include <string.h>
#include <list>

using namespace std;


CReagent::CReagent()
{
    m_reagent_qpcr_arr = NULL;
    m_reagent_dj_purify_arr = NULL;
    m_reagent_dp8_arr = NULL;
}

CReagent::~CReagent()
{
    if(m_reagent_qpcr_arr)
    {
        delete [] m_reagent_qpcr_arr;
        m_reagent_qpcr_arr = NULL;
    }

    if(m_reagent_dj_purify_arr)
    {
        delete [] m_reagent_dj_purify_arr;
        m_reagent_dj_purify_arr = NULL;
    }

    if(m_reagent_dp8_arr)
    {
        delete [] m_reagent_dp8_arr;
        m_reagent_dp8_arr = NULL;
    }   
    
}

int parse_one_reagent(Json::Value & nodeIn, std::list<reagent_describe> & listOut, int * numOut, int reagentType)
{
    if(nodeIn.empty())
    {
        return 1;
    }

    reagent_describe tempReagent;
    tempReagent.reagent_type = reagentType;
    if(nodeIn.isArray())
    {
        *numOut = nodeIn.size();
        for(int i=0;i<*numOut;i++)
        {
            Json::Value tempNode = nodeIn[i];
            Json::Value::Members listReagent = tempNode.getMemberNames();
            Json::Value::Members::iterator itReagent =  listReagent.begin();

            while(itReagent!=listReagent.end())
            {
                if((*itReagent).compare("indexX")==0)
                {
                    tempReagent.index_module_X = tempNode[*itReagent].asInt();
                }
                else if((*itReagent).compare("indexY")==0)
                {
                    tempReagent.index_module_Y = tempNode[*itReagent].asInt();
                }
                else if((*itReagent).compare("volume")==0)
                {
                    tempReagent.volumeRemain = tempNode[*itReagent].asDouble();
                }
                
                itReagent++;
            }

            // std::cout<<tempReagent.index_module_X<<","
            //          <<tempReagent.index_module_Y<<","
            //          <<tempReagent.volumeRemain<<std::endl;

            listOut.push_back(tempReagent);
            
        }
    }
    else //if(nodeIn.isObject())
    {
        *numOut = 1;
        Json::Value::Members listReagent = nodeIn.getMemberNames();
        Json::Value::Members::iterator itReagent =  listReagent.begin();

        while(itReagent!=listReagent.end())
        {
            if((*itReagent).compare("indexX")==0)
            {
                tempReagent.index_module_X = nodeIn[*itReagent].asInt();
            }
            else if((*itReagent).compare("indexY")==0)
            {
                tempReagent.index_module_Y = nodeIn[*itReagent].asInt();
            }
            else if((*itReagent).compare("volume")==0)
            {
                tempReagent.volumeRemain = nodeIn[*itReagent].asInt();
            }
            
            itReagent++;
        }
        listOut.push_back(tempReagent);
    }
    return 0;
}

void CReagent::setModuleLiquidType(int moduleIn,unsigned char liquidTypeIn)
{
    if(moduleIn<0 || moduleIn>=MAX_NUM_MODULE_LIQUID_TYPE) 
    {
       return ;
    }

    m_liquidTypeArr[moduleIn] = liquidTypeIn;
}
unsigned char CReagent::getLiquidType(int moduleIn)
{
    if(moduleIn<0 || moduleIn>=MAX_NUM_MODULE_LIQUID_TYPE) 
    {
       return 0xff;
    }
    return m_liquidTypeArr[moduleIn];
}

int parse_for_dj_purify(reagent_describe ** reagentArrOut,int *numOut,Json::Value & nodeIn)
{
    const int numdjpReagent = 4;
    std::vector<std::string> djpReagentStrings(numdjpReagent);
    djpReagentStrings[0] = "magnet";
    djpReagentStrings[1] = "split";
    djpReagentStrings[2] = "protainase";
    djpReagentStrings[3] = "helpdown";

    char * flag = new char[numdjpReagent];
    
    Json::Value::Members listReagent = nodeIn.getMemberNames();
    Json::Value::Members::iterator itReagent =  listReagent.begin();
    
    memset(flag,0,sizeof(char)*numdjpReagent);

    std::list<reagent_describe> listReagentOut(1);
    listReagentOut.clear();

    int numTemp = 0;

    int numAll = 0;

    while(itReagent!=listReagent.end())
    {
        int index = djpReagentStrings.size() - 1;
        for(;index>=0;index--)
        {
            if(flag[index])
            {
                continue;
            }
            if((*itReagent).compare(djpReagentStrings[index])==0)
            {
                numTemp = 0;
                switch(index)
                {
                    case 0:
                    {
                        parse_one_reagent(nodeIn[*itReagent], listReagentOut, &numTemp, REAGENT_MAGNET);
                        numAll += numTemp;
                    }                    
                    break;
                    case 1:
                    {
                        parse_one_reagent(nodeIn[*itReagent], listReagentOut, &numTemp, REAGENT_BREAK);
                        numAll += numTemp;
                    }
                    break;
                    case 2:
                    {
                        parse_one_reagent(nodeIn[*itReagent], listReagentOut, &numTemp, REAGENT_PROTAINASE);
                        numAll += numTemp;                        
                    }
                    break;
                    case 3:
                    {
                        parse_one_reagent(nodeIn[*itReagent], listReagentOut, &numTemp, REAGENT_HELPDOWN);
                        numAll += numTemp;                        
                    }
                    break;
                    default:
                    break;
                }

                flag[index] = 1;
                break;
            }
        }
        itReagent++;
    }

    *reagentArrOut = new reagent_describe[numAll];
    reagent_describe * pstReagent = *reagentArrOut;
    std::list<reagent_describe>::iterator itReagentResult = listReagentOut.begin();
    for(int i=0;i<numAll;i++)
    {
        if(itReagentResult==listReagentOut.end())
        {
            break;
        }
        memcpy(pstReagent,&(*itReagentResult),sizeof(reagent_describe));
        itReagentResult++;
        pstReagent++;
    }

    *numOut = numAll;

    listReagentOut.clear();

    delete flag;
    flag = NULL;

    return 0;

}

int load_one_group_reagent(const void * jsonNodeIn,reagent_describe ** reagentArrOut,int * numOut,int moduleIdIn)
{
    Json::Value * pstJsonValue = (Json::Value*) jsonNodeIn;
    Json::Value::Members listReagent = pstJsonValue->getMemberNames();
    Json::Value::Members::iterator itReagent =  listReagent.begin();
    
    if(moduleIdIn == MODULE_DJ_PURIFY)
    {
        parse_for_dj_purify(reagentArrOut,numOut,*pstJsonValue);
    }
    else if(moduleIdIn == MODULE_DP8)
    {
        //parse_for_dj_purify(reagentArrOut,numOut,*pstJsonValue);
    }

    return 0;
}

int print_reagent(reagent_describe * reagentIn)
{
    std::cout << "reagent type : "<<reagentIn->reagent_type<<"  ====="<<std::endl;
    std::cout << "index m_x: "<<reagentIn->index_module_X <<
    ",index m_y: "<<reagentIn->index_module_Y<<std::endl;
    std::cout << "volume: "<<reagentIn->volumeRemain <<std::endl<<std::endl;

}


int CReagent::init_reagent_from_config(const char * file_name)
{
    Json::Reader reader;
    Json::Value root;
 
    //从文件中读取，保证当前文件有test.json文件
    std::ifstream in;//(configFiles_json[fileId], std::ios::binary);

    if(file_name)
    {
        in.open(file_name, std::ios::binary);
    }
    else
    {
        in.open(REAGENT_FILE, std::ios::binary);
    }
    
    if( !in.is_open() )
    {
        std::cout << "Error opening file,"<<file_name<<std::endl;
        return -1; 
    }


    reader.parse(in,root);
 
    
    if(root.empty())
    {
        std::cout << "Error parse json content\n"; 
        root.clear();
        in.close();
        return -2;
    }
    
    Json::Value::Members listNameModule = root.getMemberNames();
    Json::Value::Members::iterator itRoot = listNameModule.begin();
    while(itRoot!=listNameModule.end())
    {
        std::cout<<"node name:"<<*itRoot<<std::endl;
        if((*itRoot).compare("dj_purify") == 0)
        {
            load_one_group_reagent(&root["dj_purify"], &m_reagent_dj_purify_arr, &m_num_djp_reagent,MODULE_DJ_PURIFY);
        }
        itRoot++;
    }  

    root.clear();
    in.close();


    std::cout<<"num dj purify reagent:"<<m_num_djp_reagent<<std::endl;
    reagent_describe * ptrReagent = m_reagent_dj_purify_arr;
    for(int i=0;i<m_num_djp_reagent;i++)
    {
        std::cout<<"i="<<i<<"------------"<<std::endl;
        print_reagent(ptrReagent);
        ptrReagent++;
    }

    return 0;
    
}

int get_module_id_from_reagent_type(int typeIn,int * moduleIdOut)
{
    if(typeIn>=DJP_REAGENT_START && typeIn<=DJP_REAGENT_END)
    {
        * moduleIdOut = MODULE_DJ_PURIFY;
    }
    else if(typeIn>=DJQ_REAGENT_START && typeIn<=DJQ_REAGENT_END)
    {
        * moduleIdOut = MODULE_DJ_QPCR;
    }
    else if(typeIn>=DP1_REAGENT_START && typeIn<=DP1_REAGENT_END)
    {
        * moduleIdOut = MODULE_DP1;
    }
    else if(typeIn>=DP8_REAGENT_START && typeIn<=DP8_REAGENT_END)
    {
        * moduleIdOut = MODULE_DP8;
    }

    return 0;
}

int CReagent::apply_reagent_to_suck(int typeIn, float volumeIn, reagent_describe ** pstReagentOut,float *volumnOut)
{
    reagent_describe * pstTempReagent = NULL;
    int numAll = 0;

    int moduleType = 0;

    reagent_describe * pstRetReagent = NULL;
    get_module_id_from_reagent_type(typeIn,&moduleType);

    switch(moduleType)
    {
        case MODULE_DP1:
        {
            //pstTempReagent = m_
        }
        break;
        case MODULE_DJ_PURIFY:
        {
            pstTempReagent = m_reagent_dj_purify_arr;
            numAll = m_num_djp_reagent;
        }
        break;
        case MODULE_DJ_QPCR:
        {
            pstTempReagent = m_reagent_qpcr_arr;
        }
        break;
        default:
        break;
    }

    if(pstTempReagent == NULL)
    {
        std::cout << "get_reagent_to_suck, param is not valid" <<std::endl;
        return 1;
    }
    
    while(numAll>0)
    {
        if(pstTempReagent->reagent_type == typeIn 
          && pstTempReagent->volumeRemain >= volumeIn)
        {
            pstRetReagent = pstTempReagent;
            *volumnOut = volumeIn;
            break;
        }
        numAll--;
        pstTempReagent++;

    }

    *pstReagentOut = pstRetReagent; 
    return 0;
}

int CReagent::getRemainVolume(int moudleId, location_layout* plocIn)
{
    reagent_describe * ptrReagent = NULL;
    int index = 0;
    int maxNum = 0;
    int volumeRet = -1;
    switch (moudleId)
    {
        case MODULE_DJ_PURIFY:
        {
            ptrReagent = m_reagent_dj_purify_arr;
            index = plocIn->indexY;
            maxNum = m_num_djp_reagent;
        }
        break;
        case MODULE_DJ_QPCR:
        {
            ptrReagent = m_reagent_qpcr_arr;
        }
        break;
        case MODULE_DP8:
        {
            ptrReagent = m_reagent_dp8_arr;
        }
        break;
        
        default:
            break;
    }

    if(index < maxNum && ptrReagent)
    {
        volumeRet = (ptrReagent+index)->volumeRemain;
    }

    return volumeRet;
}

void CReagent::setRemainVolume(int moudleId, location_layout* plocIn, int volumeToSet)
{
    reagent_describe * ptrReagent = NULL;
    int index = 0;
    int maxNum = 0;
    switch (moudleId)
    {
        case MODULE_DJ_PURIFY:
        {
            ptrReagent = m_reagent_dj_purify_arr;
            index = plocIn->indexY;
            maxNum = m_num_djp_reagent;
        }
        break;
        case MODULE_DJ_QPCR:
        {
            ptrReagent = m_reagent_qpcr_arr;
        }
        break;
        case MODULE_DP8:
        {
            ptrReagent = m_reagent_dp8_arr;
        }
        break;
        
        default:
            break;
    }

    if(index < maxNum)
    {
        (ptrReagent+index)->volumeRemain = volumeToSet;
    }   
}


int main1(int argc, char * argv[])
{
    
    CGpLayout * pLayout = CGpLayout::get_instance();
    location_layout paramIn;
    paramIn.location_type = DP1_TIPS;
    paramIn.indexX = 0;
    paramIn.indexY = 0;
    paramIn.column_x = 2;
    paramIn.row_y = 3;

    location_axis locResult;


    int convertRet = pLayout->convertToAxisLoc(&paramIn,&locResult);
    if(convertRet)
    {
        std::cout << "convert location failed"<<std::endl;
    }
    else
    {
        std::cout << "x = "<<locResult.x<<std::endl;
        std::cout << "y = "<<locResult.y<<std::endl;
    }

    CReagent reagent;

    reagent.init_reagent_from_config(REAGENT_FILE);
    
    reagent_describe * pstReagent = NULL;
    float volumeRet = 0;

    reagent.apply_reagent_to_suck(REAGENT_BREAK,50,&pstReagent,&volumeRet);
    
    if(pstReagent==NULL)
    {
        std::cout<<"reagent is not available"<<std::endl;
    }
    else
    {
        std::cout<<"module_x:"<<pstReagent->index_module_X<<",module_y:"<<pstReagent->index_module_Y<<std::endl;
        std::cout<<"volumeRemain:"<<pstReagent->volumeRemain<<",volumeRet:"<< volumeRet<<std::endl;
    }

    CTips tipsForSchedule;
    tipsForSchedule.init_tips_from_config(TIPS_FILE);
    //delete pLayout;
    return 0;
}

int get_tipbox_content(Json::Value & nodeIn,std::vector<std::string>& keyStrings,tip_box * tipboxOut)
{
    Json::Value::Members listKeysInJson = nodeIn.getMemberNames();
    Json::Value::Members::iterator itKey =  listKeysInJson.begin();
    
    int numKeyStrings = keyStrings.size();

    char * flag = new char[numKeyStrings]; 

    memset(flag,0,sizeof(char)*numKeyStrings);

    
    while(itKey!=listKeysInJson.end())
    {
        int index = keyStrings.size() - 1;
        for(;index>=0;index--)
        {
            if(flag[index])
            {
                continue;
            }

            if((*itKey).compare(keyStrings[index]) == 0)
            {
                switch(index)
                {
                    case 0:
                    {
                        tipboxOut->module_i_x = nodeIn[*itKey].asInt();
                    }
                    break;
                    case 1:
                    {
                       tipboxOut->module_i_y = nodeIn[*itKey].asInt();
                    }
                    break;
                    case 2:
                    {
                       tipboxOut->max_colum_x = nodeIn[*itKey].asInt();
                    }
                    break;
                    case 3:
                    {
                       tipboxOut->max_row_y = nodeIn[*itKey].asInt();
                    }
                    break;
                    default:
                    break;
                }

                flag[index] = 1;
                break;
            }
        }
        itKey++;
    }  
}

int parse_one_tipbox(Json::Value & nodeIn,std::list<tip_box> & listTipboxOut,int * numOut, int tipTypeIn)
{
    const int numKeys = 4;
    std::vector<std::string> keyStrings(numKeys);
    keyStrings[0] = "indexX";
    keyStrings[1] = "indexY";
    keyStrings[2] = "num_x";
    keyStrings[3] = "num_y";

    
    if(nodeIn.empty())
    {
        return 1;
    }

    tip_box tipBoxTemp;
    tipBoxTemp.tipType = tipTypeIn;

    if(nodeIn.isArray())
    {

        * numOut = nodeIn.size();
        for(int i=0;i<(* numOut);i++)
        {
            get_tipbox_content(nodeIn[i],keyStrings,&tipBoxTemp);
            if( tipBoxTemp.max_colum_x > 0 
            &&  tipBoxTemp.max_row_y > 0)
            {
                listTipboxOut.push_back(tipBoxTemp);
                * numOut = * numOut - 1;
            }            
        }
    }
    else
    {
        * numOut = 1;
        get_tipbox_content(nodeIn,keyStrings,&tipBoxTemp);
        listTipboxOut.push_back(tipBoxTemp);
    }

    return 0;
}


int parse_tipboxs(tip_box ** tipBoxArrOut,int * numOut,Json::Value & nodeIn)
{
    const int numTips = 3;
    std::vector<std::string> tipStrings(numTips);
    tipStrings[0] = "tip1000ul";
    tipStrings[1] = "tip200ul";
    tipStrings[2] = "tip50ul";

    char * flag = new char[numTips];
    
    Json::Value::Members listTipBox = nodeIn.getMemberNames();
    Json::Value::Members::iterator itTipBox =  listTipBox.begin();
    
    memset(flag,0,sizeof(char)*numTips);

    std::list<tip_box> listTipboxOut(1);
    listTipboxOut.clear();

    int numTemp = 0;

    int numAll = 0;

    while(itTipBox!=listTipBox.end())
    {
        int index = tipStrings.size() - 1;
        for(;index>=0;index--)
        {
            if(flag[index])
            {
                continue;
            }
            if((*itTipBox).compare(tipStrings[index])==0)
            {
                numTemp = 0;
                switch(index)
                {
                    case 0:
                    {
                        parse_one_tipbox(nodeIn[*itTipBox], listTipboxOut, &numTemp, TIP_1000UL);
                        numAll += numTemp;
                    }                    
                    break;
                    case 1:
                    {
                        parse_one_tipbox(nodeIn[*itTipBox], listTipboxOut, &numTemp, TIP_200UL);
                        numAll += numTemp;
                    }
                    break;
                    case 2:
                    {
                        parse_one_tipbox(nodeIn[*itTipBox], listTipboxOut, &numTemp, TIP_50UL);
                        numAll += numTemp;                        
                    }
                    break;
                    default:
                    break;
                }

                flag[index] = 1;
                break;
            }
        }
        itTipBox++;
    }

    *tipBoxArrOut = new tip_box[numAll];
    tip_box * pstTipbox = *tipBoxArrOut;
    std::list<tip_box>::iterator itTipsResult = listTipboxOut.begin();
    for(int i=0;i<numAll;i++)
    {
        if(itTipsResult==listTipboxOut.end())
        {
            break;
        }
        memcpy(pstTipbox,&(*itTipsResult),sizeof(tip_box));
        itTipsResult++;
        pstTipbox++;
    }

    *numOut = numAll;

    listTipboxOut.clear();

    delete [] flag;
    flag = NULL;

    return 0;
}

void print_tip_box(tip_box * pstTipBox)
{
    std::cout<<"tip type:"<<(unsigned int )pstTipBox->tipType<<std::endl;
    std::cout<<"module i x:"<<(unsigned int )pstTipBox->module_i_x<<std::endl;
    std::cout<<"module i y:"<<(unsigned int )pstTipBox->module_i_y<<std::endl;
    std::cout<<"max x:"<<(unsigned int )pstTipBox->max_colum_x<<std::endl;
    std::cout<<"max y:"<<(unsigned int )pstTipBox->max_row_y<<std::endl;
}

int generate_tips_inbox(tip_box * tipBoxIn)
{
    int max_x = tipBoxIn->max_colum_x;
    int max_y = tipBoxIn->max_row_y;

    tipBoxIn->tipList = new tip_describe[max_x*max_y];

    tipBoxIn->tipMem = tipBoxIn->tipList;
    tipBoxIn->status = ALL_AVAILEBLE;
    tipBoxIn->remainNum = max_x*max_y;
    tip_describe * pstOneTip = tipBoxIn->tipList;

    tip_describe * pstOneTipPrevious = pstOneTip;


    for(int indexX=0;indexX<max_x;indexX++)
    {
        for(int indexY=0;indexY<max_y;indexY++)
        {
           pstOneTip->index_x =  indexX;
           pstOneTip->index_y =  indexY;
           pstOneTip->isAvailable = 1;

           if(tipBoxIn->tipList!=pstOneTip)
           {
              pstOneTipPrevious->next = pstOneTip ;
              pstOneTipPrevious++;
           }
           pstOneTip++;
        }
    }
    
}

CTips::CTips()
{
    m_tip_box_dp8_arr = NULL;
    m_numDp8TipBox = 0;
    m_tip_box_dp1_arr = NULL;
    m_numDp1TipBox = 0;
}

CTips::~CTips()
{
    if(m_tip_box_dp8_arr)
    {
        tip_box * pstTipBox = m_tip_box_dp8_arr;
        for(int i=0;i<m_numDp8TipBox;i++)
        {
            if(pstTipBox->tipMem)
            {
                delete [] pstTipBox->tipMem;
                pstTipBox->tipMem = NULL;
            }
            pstTipBox++;
        }
        delete [] m_tip_box_dp8_arr;
        m_tip_box_dp8_arr = NULL; 
    }
    m_numDp8TipBox = 0;

    if(m_tip_box_dp1_arr)
    {
        tip_box * pstTipBox = m_tip_box_dp1_arr;
        for(int i=0;i<m_numDp1TipBox;i++)
        {
            if(pstTipBox->tipMem)
            {
                delete [] pstTipBox->tipMem;
                pstTipBox->tipMem = NULL;
            }
            pstTipBox++;
        }
        delete [] m_tip_box_dp1_arr;
        m_tip_box_dp1_arr = NULL; 
    }
    m_numDp1TipBox = 0;
}

int CTips::init_tips_from_config(const char * file_name)
{
    Json::Reader reader;
    Json::Value root;
 
    //从文件中读取，保证当前文件有test.json文件
    std::ifstream in;//(configFiles_json[fileId], std::ios::binary);

    if(file_name)
    {
        in.open(file_name, std::ios::binary);
    }
    else
    {
        in.open(TIPS_FILE, std::ios::binary);
    }
    
    if( !in.is_open() )
    {
        std::cout << "init_tips_from_config, Error opening file,"<<file_name<<std::endl;
        
        root.clear();
        in.close();
        return -1; 
    }


    reader.parse(in,root);
 
    
    if(root.empty())
    {
        std::cout << "init_tips_from_config, Error parse json content\n"; 
        return -2;
    }
    
    Json::Value::Members listNameModule = root.getMemberNames();
    Json::Value::Members::iterator itRoot = listNameModule.begin();
    while(itRoot!=listNameModule.end())
    {
        std::cout<<"node name:"<<*itRoot<<std::endl;
        if((*itRoot).compare("dp1") == 0)
        {
            parse_tipboxs(&m_tip_box_dp1_arr,&m_numDp1TipBox,root["dp1"]);
        }
        else if((*itRoot).compare("dp8") == 0)
        {
            parse_tipboxs(&m_tip_box_dp8_arr,&m_numDp8TipBox,root["dp8"]);
        }
        itRoot++;
    }  

    root.clear();
    in.close();


    std::cout<<"num tp1 tip box:"<<m_numDp1TipBox<<std::endl;
    tip_box * ptrTipBox = m_tip_box_dp1_arr;
    for(int i=0;i<m_numDp1TipBox;i++)
    {
        std::cout<<"i="<<i<<"------------"<<std::endl;
        
        print_tip_box(ptrTipBox);
        ptrTipBox++;
    }

    return 0;    
}

int CTips::apply_tip_to_use(int userType, int tipType,tip_box **pstTipBoxOut, tip_describe ** tipOut)
{
    tip_box * pstTipBoxTemp = NULL;
    int numBoxTemp = 0;

    if(userType == MODULE_DP1)
    {
        pstTipBoxTemp = m_tip_box_dp1_arr;
        numBoxTemp = m_numDp1TipBox;
    }
    else if(userType == MODULE_DP8)
    {
        pstTipBoxTemp = m_tip_box_dp1_arr;
        numBoxTemp = m_numDp1TipBox;       
    }

    for(int i=0;i<numBoxTemp;i++)
    {
        if(  pstTipBoxTemp->tipType == tipType 
           &&pstTipBoxTemp->remainNum > 0)
        {
            *pstTipBoxOut = pstTipBoxTemp;
            * tipOut = pstTipBoxTemp->tipList;
        }
    }
}

int CTips::update_tip(tip_box *pstTipBoxOut)
{
    pstTipBoxOut->remainNum -= 1;
    if(pstTipBoxOut->remainNum == 0)
    {
       pstTipBoxOut->status = NO_AVLAIBLE;
    }
    else
    {
       pstTipBoxOut->status = PART_AVAILABLE;
    }

    pstTipBoxOut->tipList->isAvailable = 0;

    pstTipBoxOut->tipList = pstTipBoxOut->tipList->next;
}

void CTips::setCurrTipType(int moduleIn,int tipType)
{
    if(moduleIn==MODULE_DP1)
    {
        m_currentDp1TipType = tipType;
    }
    else if(moduleIn==MODULE_DP8)
    {
        m_currentDp8TipType = tipType;
    }
	else if(moduleIn==MODULE_DP8_1)
	{
	   m_currentDp8_1TipType = tipType;
	}
}
int CTips::getCurrTipType(int moduleIn)
{
    if(moduleIn==MODULE_DP1)
    {
        return  m_currentDp1TipType;
    }
    else if(moduleIn==MODULE_DP8)
    {
        return m_currentDp8TipType;
    }
    else if(moduleIn==MODULE_DP8_1)
    {
        return m_currentDp8_1TipType;
    }
} 

CTube_8Holes::CTube_8Holes()
{
    m_tube8_arr_a = new tube8_describe[MAX_NUM_TUBE8_ONE_AREA];
    m_tube8_arr_b = new tube8_describe[MAX_NUM_TUBE8_ONE_AREA];

    memset(paramMem_a,0,sizeof(char *)*MAX_NUM_TUBE8_ONE_AREA);

    memset(paramMem_b,0,sizeof(char *)*MAX_NUM_TUBE8_ONE_AREA);
}
CTube_8Holes::~CTube_8Holes()
{
    delete [] m_tube8_arr_a;
    delete [] m_tube8_arr_b;

    for(int i=0;i<MAX_NUM_TUBE8_ONE_AREA;i++)
    {
        if(paramMem_a[i])
        {
            delete [] paramMem_a[i];
            paramMem_a[i] = NULL;
        }
        
        if(paramMem_b[i])
        {
            delete [] paramMem_b[i];
            paramMem_b[i] = NULL;
        }
        
    }
}

int CTube_8Holes::getRemainVolume(location_layout * locIn, int tube8IdIn)
{
    tube8_describe * pTube8 = NULL;
    int indexHole = locIn->row_y;
    int maxNumTube = 6;
    int retVolume = -1;
    int indexTube = 0;
    int maxNumHoles = 8;
    if(tube8IdIn<16)
    {
        pTube8 = m_tube8_arr_a;
        indexTube = tube8IdIn - 16;
    }
    else
    {
        pTube8 = m_tube8_arr_b;
        indexTube = tube8IdIn;
    }
    
    if(pTube8 
    && indexTube < maxNumTube
    && indexHole < maxNumHoles)
    {
        retVolume = (pTube8 + indexTube)->volumeRemain[indexHole];
    }

    return retVolume;
    
}
void CTube_8Holes::setRemainVolume(location_layout * locIn,int tube8IdIn, int volume)
{
    tube8_describe * pTube8 = NULL;
    int indexHole = locIn->row_y;
    int maxNumTube = 6;
    int retVolume = -1;
    int indexTube = 0;
    int maxNumHoles = 8;
    if(tube8IdIn<16)
    {
        pTube8 = m_tube8_arr_a;
        indexTube = tube8IdIn - 16;
    }
    else
    {
        pTube8 = m_tube8_arr_b;
        indexTube = tube8IdIn;
    }
    
    if(pTube8 
    && indexTube < maxNumTube
    && indexHole < maxNumHoles)
    {
        (pTube8 + indexTube)->volumeRemain[indexHole] = volume;
    }
}

int CTube_8Holes::init_tube8(int tube8Id,int areaId)
{
    tube8_describe * pTube8 = NULL;

    char * pParamMem = NULL;

    if(areaId==0)
    {
        pTube8 = m_tube8_arr_a;
        if(tube8Id>=0&&tube8Id<MAX_NUM_TUBE8_ONE_AREA)
        {
            pParamMem = paramMem_a[tube8Id];
            memset((pTube8+tube8Id),0,sizeof(tube8_describe));

            (pTube8+tube8Id)->tube8InitLoc.areaId = AREA_PURIFY_REAGENT_PRE_A;
            (pTube8+tube8Id)->tube8InitLoc.indexX_column = tube8Id%2;
            (pTube8+tube8Id)->tube8InitLoc.indexY_row = tube8Id/2;

            memcpy(&((pTube8+tube8Id)->tube8CurrLoc),&((pTube8+tube8Id)->tube8InitLoc),sizeof(loc_base));
        }
    }
    else
    {
        pTube8 = m_tube8_arr_b;
        if(tube8Id>=0&&tube8Id<MAX_NUM_TUBE8_ONE_AREA)
        {
            pParamMem = paramMem_b[tube8Id];
            memset((pTube8+tube8Id),0,sizeof(tube8_describe));

            (pTube8+tube8Id)->tube8InitLoc.areaId = AREA_PURIFY_REAGENT_PRE_B;
            (pTube8+tube8Id)->tube8InitLoc.indexX_column = tube8Id%2;
            (pTube8+tube8Id)->tube8InitLoc.indexY_row = tube8Id/2;

            memcpy(&((pTube8+tube8Id)->tube8CurrLoc),&((pTube8+tube8Id)->tube8InitLoc),sizeof(loc_base));
        }
    }

    if(pParamMem == NULL)
    {
        pParamMem = new  char[MAX_LEN_PARAM];
    }

    return 0;
    
}

CResource_Manage::CResource_Manage()
{
    m_pstTube8 = new CTube_8Holes();
    m_pstTips = new CTips();
    m_pstReagent =  new CReagent();

    m_curr_purify_pump = PURIFY_PUMP_SMALL;
}

CResource_Manage::~CResource_Manage()
{
    delete m_pstTube8;
    delete m_pstTips;
    delete m_pstReagent;
}

void CResource_Manage::set_curr_tip_type(int moduleIn,int tipTypeIn)
{
   m_pstTips->setCurrTipType(moduleIn,tipTypeIn);
}

int CResource_Manage::get_curr_tip_type(int moduleIn)
{
  return m_pstTips->getCurrTipType(moduleIn);
}

void CResource_Manage::set_curr_liquid_type(int moduleIn,int tipTypeIn)
{
   m_pstReagent->setModuleLiquidType(moduleIn,tipTypeIn);
}

unsigned char CResource_Manage::get_curr_liquid_type(int moduleIn)
{
   return m_pstReagent->getLiquidType(moduleIn);
}

void CResource_Manage::set_purify_pump_type(int purifyPumpTpeIn)
{
   m_curr_purify_pump = purifyPumpTpeIn;
}

int CResource_Manage::get_purify_pump_type(void)
{
    return m_curr_purify_pump;
}